package com.misboot.document.controller;

import com.alibaba.fastjson.JSONArray;
import com.lowagie.text.pdf.AcroFields;
import com.lowagie.text.pdf.PdfPKCS7;
import com.lowagie.text.pdf.PdfReader;
import com.misboot.document.model.OaSignaturesCa;
import com.misboot.document.service.FileService;
import com.misboot.document.service.OaSignaturesCaService;
import com.misboot.document.utils.wps.Token;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import sun.security.x509.X509CertImpl;

import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.GeneralSecurityException;
import java.security.KeyStore;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


/**
 * @MethodName 电子签章验证
 * @Description TODO
 * @Param null
 * @Return
 * @Author 朱永敬<zhuyongjing @ zuoyour.com>
 * @Date 2023/7/4 17:02
 */
@Controller
@RequestMapping("/selfSigned")
public class IsSelfSignedController extends DocumentBaseController {

    static Logger logger = LoggerFactory.getLogger(IsSelfSignedController.class);

    @Autowired
    private OaSignaturesCaService oaSignaturesCaService;

    /**
     * @MethodName 验签方法
     * @Description TODO
     * @Param pdfFilePath
     * @Param keystorePath
     * @Param keystorePassword
     * @Return boolean
     * @Author 朱永敬<zhuyongjing @ zuoyour.com>
     * @Date 2023/7/4 08:59
     */
    @ResponseBody
    @RequestMapping(value = "/verifySignature")
    public Object verifySignature(@RequestPart("file") MultipartFile file,String pdfPath, String caUuid) {
        String filePath = pdfPath;
        int  trueCount  =0;
        int falseCount  =0;
        try {
            KeyStore keystore = loadKeyStore(caUuid);
            PdfReader reader = null;
            if (file != null ){
                reader = new PdfReader(file.getBytes());
            }else {
                reader = new PdfReader(filePath);
            }

            AcroFields acroFields = reader.getAcroFields();
            List<String> signatureNames = acroFields.getSignatureNames();
            for (String signatureName : signatureNames) {
                System.out.println("Verifying signature: " + signatureName);
                PdfPKCS7 pkcs7 = acroFields.verifySignature(signatureName);
                boolean isSelfSigned = isSelfSigned(pkcs7.getSigningCertificate(), keystore);
                if (isSelfSigned) {
                    System.out.println("签名是自签名的");
                    trueCount = trueCount +1;
                } else {
                    System.out.println("签名不是自签名的");
                    falseCount = falseCount +1;
                }
            }
            reader.close();
            Map<String,Object> map = new HashMap<>();
            map.put("total",signatureNames.size());
            map.put("trueCount",trueCount);
            map.put("falseCount",falseCount);
            return map;
        } catch (IOException | GeneralSecurityException e) {
            e.printStackTrace();
        }

        return false;
    }


    private  KeyStore loadKeyStore(String caUuid) throws IOException, GeneralSecurityException {
        //获取CA证书
        OaSignaturesCa oaSignaturesCa = oaSignaturesCaService.selectByPrimaryKey(caUuid);
        String keypass = "OTI0NTRGRjE0Q0Q3NjQyQTc5MjBBNUQ5Q0QwQjAzNEM=";
        char[] PASSWORD = keypass.toCharArray();
        //读取keystore ，获得私钥和证书链
        KeyStore keystore = null;
        keystore = KeyStore.getInstance("JKS");
        keystore.load(byteArrayToInputStream(oaSignaturesCa.getKeystore()), PASSWORD);

        return keystore;
    }

    private static boolean isSelfSigned(X509Certificate certificate, KeyStore keystore) throws GeneralSecurityException {
        List<Certificate> certificateChain = new ArrayList<>();
        certificateChain.add(certificate);
        X509Certificate signerCert = certificate;

        // 查找证书链的根证书
        Certificate rootCert = findRootCertificate(signerCert, certificateChain, keystore);

        // 检查根证书和签名证书是否相同
//        Map<String,Object> map = new HashMap<>();
//        map.put("isSelfSigned",signerCert.equals(rootCert));
//        map.put("caInfo",((X509CertImpl) rootCert).getIssuerDN().toString());
        return signerCert.equals(rootCert);
    }

    private static Certificate findRootCertificate(X509Certificate signerCert, List<Certificate> certificateChain, KeyStore keystore) throws GeneralSecurityException {
        String alias = (String) keystore.aliases().nextElement();
        Certificate issuerCert = keystore.getCertificate(alias);
        certificateChain.add(issuerCert);

        if (isSelfSigned(issuerCert)) {
            return issuerCert;
        } else {
            return findRootCertificate((X509Certificate) issuerCert, certificateChain, keystore);
        }
    }

    private static boolean isSelfSigned(Certificate certificate) throws GeneralSecurityException {
        X509Certificate x509Cert = (X509Certificate) certificate;
        try {
            x509Cert.verify(x509Cert.getPublicKey());
            return true;
        } catch (Exception e) {
            return false;
        }
    }


    /**
     * 将byte数组转换为InputStream
     *
     * @param bytes 待转换的byte数组
     * @return InputStream对象
     * @throws IOException 转换异常
     */
    public static InputStream byteArrayToInputStream(byte[] bytes) throws IOException {
        if (bytes == null) {
            return null;
        }
        ByteArrayInputStream inputStream = new ByteArrayInputStream(bytes);
        return inputStream;
    }


}
